﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KPIS.DBM;
using KPIS.GERP.GHRMS.MODEL;
using System.Reflection;
using System.Data;
using System.ComponentModel;

namespace KPIS.GERP.GHRMS.DAL
{
    public static class TypeExtensions
    {
        public static bool IsNullableType(this Type type)
        {
            return type.IsGenericType
            && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
        }
    }
    public class CollectionHelper
    {
        private CollectionHelper()
        {
        }

        public static DataTable ConvertTo<T>(IList<T> list)
        {
            DataTable table = CreateTable<T>();
            Type entityType = typeof(T);
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);

            foreach (T item in list)
            {
                DataRow row = table.NewRow();

                foreach (PropertyDescriptor prop in properties)
                {
                    row[prop.Name] = prop.GetValue(item);
                }

                table.Rows.Add(row);
            }

            return table;
        }

        public static IList<T> ConvertTo<T>(IList<DataRow> rows)
        {
            IList<T> list = null;

            if (rows != null)
            {
                list = new List<T>();

                foreach (DataRow row in rows)
                {
                    T item = CreateItem<T>(row);
                    list.Add(item);
                }
            }

            return list;
        }

        public static IList<T> ConvertTo<T>(DataTable table)
        {
            if (table == null)
            {
                return null;
            }

            List<DataRow> rows = new List<DataRow>();

            foreach (DataRow row in table.Rows)
            {
                rows.Add(row);
            }

            return ConvertTo<T>(rows);
        }

        public static T ConvertType<T>(object value)
        {
            T obj = default(T);

            switch (value.GetType().ToString())
            {
                case "string":
                    break;
            }

            return obj;
        }

        public static T CreateItem<T>(DataRow row)
        {
            T obj = default(T);
            if (row != null)
            {
                obj = Activator.CreateInstance<T>();

                foreach (DataColumn column in row.Table.Columns)
                {
                    PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);


                    if (prop != null)
                    {
                        try
                        {
                            object value = (row[column.ColumnName] != DBNull.Value ? row[column.ColumnName] : null);

                            if (value != null)
                            {
                                Type typeDTB = value.GetType();
                                Type typeList = prop.PropertyType;
                            }
                            if (value != null && value.GetType() == typeof(UInt32))
                            {
                                value = Convert.ToInt32(value);
                            }
                            else if (value != null && value.GetType() == typeof(Int64))
                            {
                                value = Convert.ToDecimal(value);
                            }
                            else if (value != null && value.GetType() == typeof(Decimal))
                            {
                               // if (value)
                                value = Convert.ToDouble(value);
                            }
                            if (value != null)
                            {
                                if (prop.PropertyType.IsNullableType())
                                {
                                    var targetType = prop.PropertyType.IsNullableType()
                                        ? Nullable.GetUnderlyingType(prop.PropertyType)
                                        : prop.PropertyType;
                                    var convertedValue = Convert.ChangeType(value, targetType);
                                    prop.SetValue(obj, convertedValue, null);
                                }
                                else {
                                    prop.SetValue(obj, value, null);
                                }
                            }
                            else
                            {
                                prop.SetValue(obj, value, null);
                            }
                            //prop.SetValue(obj, Convert.ChangeType(45.0, Nullable.GetUnderlyingType(prop.PropertyType)), null);

                            
                        }
                        catch (Exception ex)
                        {
                            // You can log something here
                            throw ex;
                        }
                    }
                }
            }

            return obj;
        }

        public static DataTable CreateTable<T>()
        {
            Type entityType = typeof(T);
            DataTable table = new DataTable(entityType.Name);
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);

            foreach (PropertyDescriptor prop in properties)
            {
                table.Columns.Add(prop.Name, prop.PropertyType);
            }

            return table;
        }
    }

}
